#include "stdafx.h"
#include "gui.h"
#include "cmd.h"
#include <qtreewidget.h>
#include <qfile.h>
#include <qdir.h>
#include <QEnvPath.h>
#include <QEnvStatus.h>
#include <qprocess.h>
#include <qfiledialog.h>

SnapshotGui::SnapshotGui( QWidget * w ) : QMainWindow( w )
{ 
	mBar = NULL;
	ui.setupUi(this);
	QEnvStatus::_register( this, ui.statusbar, ui.logOutput );
	
	setupUi();

	refreshSdk();
}
SnapshotGui::~SnapshotGui(){
	mSdk.destroy(true);
}

QTreeWidgetItem* SnapshotGui::createNode( const StringVector& labels, QTreeWidgetItem * parent )
{
	QTreeWidgetItem * itm = NULL;
	if( !parent ){
		itm = new QTreeWidgetItem( *mSdk, labels );
		ui.repoTree->addTopLevelItem( itm );
	}
	else{
		itm = new QTreeWidgetItem( parent, labels );
		parent->addChild( itm );
	}
	itm->setExpanded( true );
	itm->setFlags( Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsSelectable );
	itm->setCheckState( 0, Qt::Unchecked );
	return itm;
}
void SnapshotGui::setupUi()
{
#if defined(NDEBUG)
	ui.logDock->close();
#endif

	QStackedWidget * tabs = ui.repoStack;

	mSdk = ui.repoTree;
	mSdk->setSnapshotTable( ui.snapshotTable );
	mSdk->setStackWidget( tabs );
	mSdk->setColumnCount( 2 );
	mSdk->setHeaderLabels( StringVector() << tr("Project") << tr("Extra") );
	mSdk->setColumnWidth( 0, mSdk->sizeHint().width()*0.8 );
	
	mHome = createNode( StringVector() << tr("Home") );
	mBar = new QProgressBar(this);
	ui.statusbar->addPermanentWidget( mBar );
	mBar->setVisible( false );
	mBar->setFixedHeight( 20 );
}

void SnapshotGui::refreshSdk( const String &proj_ext )
{
	mSdk->clear();

	std::map<std::string, std::vector<SnapshotItemPtr>> m;
	std::vector<std::string> v0;
	GetDirectories( v0, homePath, proj_ext, true );

	for( std::vector<std::string>::iterator ii=v0.begin(); ii != v0.end(); ii++ )
	{
		QEnvPath project( *ii );
		QEnvPath projRelPath(project.makeRelative( QEnvPath(homePath) ));
		QEnvPath projBranch(QEnvPath(projRelPath).rootDir());
		if( !projRelPath.empty() )
		{
			SnapshotItem * itm = new SnapshotItem( false, project.fileName(false), projRelPath, projBranch );
			itm->setPage( new SnapshotPage( itm, ui.repoStack ) );
			mSdk->push_back( itm );
			m[projBranch.path().data()].push_back( SnapshotItemPtr(itm) );
		}
	}

	for( auto i=m.begin(); i!=m.end(); i++ )
	{
		std::stringstream n;
		n << i->second.size() << " childs";
		QTreeWidgetItem * root = createNode( StringVector() << i->first << n.str() );
		SnapshotItem * pitm = new SnapshotItem( true, i->first, QEnvPath(i->first), i->first );
		pitm->setPage( new SnapshotPage( pitm, ui.repoStack ) );
		pitm->setItem( root );
		mSdk->push_back( pitm );
		
		if( i==m.begin() )
		{
			pitm->getPage()->setCurrent();
		}

		for( auto j=i->second.begin(); j!=i->second.end(); j++ )
		{
			QTreeWidgetItem * child = createNode( StringVector()<< j->get()->getName() << j->get()->getBranch(), root );
			j->get()->setItem( child );
		}
	}
}
void SnapshotGui::on_buildSnapshot_clicked()
{
	bool det=false;
	size_t cnt = 0;
	for( auto i=mSdk->begin(); i!=mSdk->end(); i++ )
	{
		if( i->second->isAdded() && !i->second->isRepository() ){ det = true; cnt ++; }
	}
	if( !det )
	{
		QMessageBox::warning( this, "No selection", "Nothing to snapshot, select at least 1 project !");
		return;
	}
	QString loc("7z.exe");
	if( !QFile(loc).exists() )
	{
		loc = QFileDialog::getOpenFileName( this, "Missing 7-zip Executable", "./", "All 7-zip tools (7z.exe;7za.exe;7zr.exe);;" );
	}

	if( loc.isEmpty() )
		return;

	QEnvPath base(getenv("LIT_HOME"));

	if( base.empty() ) base = "./";
	else base = base.path().data() + "/snapshots/";
	
	String v(mSdk->findVersion());
	String v2(v); v2.replace( " ", "_" );

	QFileDialog dialog;
	dialog.setOptions( QFileDialog::Option::DontUseNativeDialog );
    dialog.setFileMode(QFileDialog::FileMode::AnyFile);
    dialog.setAcceptMode(QFileDialog::AcceptSave);
    dialog.setDirectory(base);
	dialog.setNameFilter( "Sdk Snapshot (*.sdksnap);;" );
    dialog.selectFile(v2+".sdksnap");   // magic happens here
    int ret = dialog.exec();
	if( ret == QDialog::Accepted )
	{
		QStringList lst = dialog.selectedFiles();
		if( lst.isEmpty() ) return;
		QString out(lst.at(0));
		if( QFile(out).exists() ) QFile(out).remove( );
		QProcess proc( this );
		size_t curid = 0;
		mBar->setRange( 0, cnt );
		mBar->setValue( 0 );
		mBar->setVisible( true );
		for( auto i=mSdk->begin(); i!=mSdk->end(); i++ )
		{
			if( i->second->isAdded() && !i->second->isRepository() )
			{
				QStringList cmd("a");
				String fname(QEnvPath(getenv("LIT_HOME")).path()+QEnvPath::Separator+i->second->getPath().parentDir().path() );
				QEnvStatus::addStatus( "Adding "+fname );
				cmd << QString(out.trimmed()) <<  fname;		
				proc.setProcessChannelMode(QProcess::MergedChannels);
				proc.start( loc, cmd, QProcess::ReadWrite );
				if( !proc.waitForStarted( -1 ) )
				{
					QEnvStatus::addStatus( "Couldn't start 7-zip process !" );
					return;
				}
				QEnvStatus::addStatus( "Running 7-zip with command: "+cmd.join(" ") );
				// Wait for it to start
				while(proc.waitForReadyRead(250)){
					QString ret(proc.readAll());
					if( !ret.isEmpty() )
					QEnvStatus::addStatus( ret );
				}
				
				mBar->setValue( curid );
				proc.waitForFinished( -1 );

				curid++;
			}
		}
			
		mBar->setValue( cnt );
	}
	
}
void SnapshotGui::on_actionUsage_triggered()
{
	QMessageBox::about( this, "Usage", usage().c_str() );
}